package com.mm.util.common;

import cn.hutool.core.date.DateUtil;

import java.time.Instant;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.ZonedDateTime;
import java.util.Date;

/**
 * @Description 日期根据时区转换
 * @Date 2024/3/14 上午10:16
 * @Author yanglin
 **/
public class DateConverter {

    /**
     * ZonedDateTime日期时区转换
     *
     * @param dateTime
     * @param toZone   转换后时区
     * @return
     */
    public static ZonedDateTime convertTimeZoneToTimeZone(ZonedDateTime dateTime, String toZone) {
        ZoneId toZoneId = ZoneId.of(toZone);
        ZonedDateTime toDateTime = dateTime.withZoneSameInstant(toZoneId);
        return toDateTime;
    }

    /**
     * ZonedDateTime日期时区转换
     *
     * @param dateTime
     * @param fromZone 当前时区
     * @param toZone   转换后时区
     * @return
     */
    public static Date convertZonedDateTimeToDate(ZonedDateTime dateTime, String fromZone, String toZone) {
        ZoneId fromZoneId = ZoneId.of(fromZone);
        ZoneId toZoneId = ZoneId.of(toZone);
        ZonedDateTime toDateTime = dateTime.withZoneSameInstant(toZoneId)
                .withZoneSameLocal(fromZoneId);
        return Date.from(toDateTime.toInstant());
    }


    /**
     * LocalDateTime日期时区转换
     *
     * @param date
     * @param fromZone 当前时区
     * @param toZone   转换后时区
     * @return
     */
    public static Date convertLocalDateTimeToDate(LocalDateTime date, String fromZone, String toZone){
        ZoneId fromZoneId = ZoneId.of(fromZone);
        ZoneId toZoneId = ZoneId.of(toZone);
        Instant instant = date.atZone(fromZoneId).toInstant();
        ZonedDateTime dateTime = ZonedDateTime.ofInstant(instant, fromZoneId);
        ZonedDateTime toDateTime = dateTime.withZoneSameInstant(toZoneId).withZoneSameLocal(fromZoneId);
        return Date.from(toDateTime.toInstant());
    }

    /**
     * LocalDateTime日期时区转换
     *
     * @param date
     * @param fromZone 当前时区
     * @param toZone   转换后时区
     * @return
     */
    public static Date convertLocalDateToDate(LocalDate date, String fromZone, String toZone){
        ZoneId fromZoneId = ZoneId.of(fromZone);
        ZoneId toZoneId = ZoneId.of(toZone);
        ZonedDateTime dateTime = date.atStartOfDay(fromZoneId);
        ZonedDateTime toDateTime = dateTime.withZoneSameInstant(toZoneId).withZoneSameLocal(fromZoneId);
        return Date.from(toDateTime.toInstant());
    }

    /**
     * Date日期时区转换
     *
     * @param date
     * @param fromZone 当前时区
     * @param toZone   转换后时区
     * @return
     */
    public static Date convertDateToDate(Date date, String fromZone, String toZone){
        ZoneId fromZoneId = ZoneId.of(fromZone);
        ZoneId toZoneId = ZoneId.of(toZone);
        Instant instant = date.toInstant();
        ZonedDateTime dateTime = ZonedDateTime.ofInstant(instant, fromZoneId);
        ZonedDateTime toDateTime = dateTime.withZoneSameInstant(toZoneId).withZoneSameLocal(fromZoneId);
        return Date.from(toDateTime.toInstant());
    }

    public static void main(String[] args) {
        Date now = DateUtil.date();
        ZoneId currentSysZone = ZoneId.systemDefault();
        System.out.println("[当前时间]：" + now + "  [当前系统时区]:" + currentSysZone);

        String fromZone = "Asia/Shanghai";
        String toZone = "Asia/Tokyo";
        ZoneId fromZoneId = ZoneId.of(fromZone);
        ZoneId toZoneId = ZoneId.of(toZone);
        // 当前时间上海转换为东京时区 Asia/Tokyo 差一个小时
        System.out.println("----------------------------------------[convertTimeZoneToTimeZone]-------------------------------------------");
        ZonedDateTime dateTime1 = ZonedDateTime.now(fromZoneId);
        ZonedDateTime zonedDateTime1 = convertTimeZoneToTimeZone(dateTime1, toZone);
        System.out.println("[转换前时区]：" + dateTime1.getZone() + "  [转换前时间]:" + dateTime1.toLocalDateTime());
        System.out.println("[转换后时区]：" + zonedDateTime1.getZone() + "  [转换后时间]:" + zonedDateTime1.toLocalDateTime());

        System.out.println("----------------------------------------[convertZonedDateTimeToDate]-------------------------------------------");
        ZonedDateTime dateTime2 = ZonedDateTime.now(fromZoneId);
        Date zonedDateTime2 = convertZonedDateTimeToDate(dateTime1, fromZone, toZone);
        System.out.println("[转换前时区]：" + dateTime2.getZone() + "  [转换前时间]:" + dateTime2.toLocalDateTime());
        System.out.println("[转换后时区]：" + toZone + "  [转换后时间]:" + zonedDateTime2);

        System.out.println("----------------------------------------[convertLocalDateTimeToDate]-------------------------------------------");
        LocalDateTime dateTime3 = LocalDateTime.now();
        Date zonedDateTime3 = convertLocalDateTimeToDate(dateTime3, fromZone, toZone);
        System.out.println("[转换前时区]：" + fromZone + "  [转换前时间]:" + dateTime3);
        System.out.println("[转换后时区]：" + toZone + "  [转换后时间]:" + zonedDateTime3);

        System.out.println("----------------------------------------[convertLocalDateToDate]-------------------------------------------");
        LocalDate dateTime4 = LocalDate.now();
        Date zonedDateTime4 = convertLocalDateToDate(dateTime4, fromZone, toZone);
        System.out.println("[转换前时区]：" + fromZone + "  [转换前时间]:" + dateTime4);
        System.out.println("[转换后时区]：" + toZone + "  [转换后时间]:" + zonedDateTime4);

        System.out.println("----------------------------------------[convertDateToDate]-------------------------------------------");
        Date zonedDateTime5 = convertDateToDate(now, fromZone, toZone);
        System.out.println("[转换前时区]：" + fromZone + "  [转换前时间]:" + now);
        System.out.println("[转换后时区]：" + toZone + "  [转换后时间]:" + zonedDateTime5);
    }

}
